package icu.zlz.emqx.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.alibaba.nacos.shaded.com.google.gson.JsonObject;
import icu.zlz.common.core.exception.ServiceException;
import icu.zlz.common.core.utils.DateUtils;
import icu.zlz.common.core.utils.StringUtils;
import icu.zlz.common.core.utils.uuid.IdUtils;
import icu.zlz.common.core.web.domain.AjaxResult;
import icu.zlz.common.security.utils.SecurityUtils;
import icu.zlz.emqx.domain.IotGroupUser;
import icu.zlz.emqx.domain.IotTopic;
import icu.zlz.emqx.mapper.IotGroupUserMapper;
import icu.zlz.emqx.mapper.IotTopicMapper;
import icu.zlz.emqx.utils.MqttTopicValidator;
import org.apache.commons.lang3.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import icu.zlz.emqx.mapper.IotGroupMapper;
import icu.zlz.emqx.domain.IotGroup;
import icu.zlz.emqx.service.IIotGroupService;
import org.springframework.transaction.annotation.Transactional;
import icu.zlz.common.core.utils.AESUtil;
import icu.zlz.common.core.utils.RsaUtils;

import javax.annotation.Resource;

/**
 * 设备组Service业务层处理
 *
 * @author zangs
 * @since 2024-12-27
 */
@Service
public class IotGroupServiceImpl implements IIotGroupService {
    private static final Logger logger = LoggerFactory.getLogger(IotGroupServiceImpl.class);


    /**
     * 无权限
     */
    public static final String NO_PERMISSIONS = "0000000000";
    /**
     * 添加用户权限
     */
    public static final Integer ADD_USER_PERMISSIONS = 2;
    /**
     * 删除用户权限
     */
    public static final Integer DELETE_USER_PERMISSIONS = 1;


    @Resource
    private IotGroupMapper iotGroupMapper;
    @Resource
    private IotGroupUserMapper iotGroupUserMapper;
    @Resource
    private MqttAuthService mqttAuthService;
    @Resource
    private IotTopicMapper iotTopicMapper;

    @Value("${secretkey.mysqlAES}")
    private String mysqlAES;

    @Value("${secretkey.privateKeyRSA}")
    private String privateKeyRSA;

    /**
     * 查询设备组
     *
     * @param groupId 设备组主键
     * @return 设备组
     */
    @Override
    public IotGroup selectIotGroupByGroupId(Long groupId) {
        Long userId = SecurityUtils.getUserId();
        if (SecurityUtils.isAdmin(userId)) {
            return iotGroupMapper.selectIotGroupByGroupIdAndUserId(groupId, null);
        } else {
            //确保查询的数据属于他加入的或者创建的群组
            return iotGroupMapper.selectIotGroupByGroupIdAndUserId(groupId, userId);
        }

    }

    /**
     * 查询设备组列表
     *
     * @param iotGroup 设备组
     * @return 设备组
     */
    @Override
    public List<IotGroup> selectIotGroupList(IotGroup iotGroup) {
        Integer type = iotGroup.getType();
        if (type < 0 || type > 3) {
            // 如果不是，则抛出  异常
            throw new ServiceException("The type value must be '0', '1', '2', or '3'.");
        }
        Long userId = SecurityUtils.getUserId();
        iotGroup.setUserId(userId);
        boolean admin = SecurityUtils.isAdmin(userId);
        if (!admin) {
            if (iotGroup.getType() == 0) {
                iotGroup.setType(1);
            }
        }
        List<IotGroup> iotGroups = iotGroupMapper.selectIotGroupList(iotGroup);
        for (IotGroup item : iotGroups) {
            try {
                //解密数据
                String v = AESUtil.decrypt(mysqlAES, item.getSecretValue());
                item.setSecretValue(RsaUtils.encryptByPrivateKey(privateKeyRSA, v));
            } catch (Exception e) {
                logger.error(e.getMessage());
            }
        }
        return iotGroups;

    }

    /**
     * 新增设备组
     *
     * @param iotGroup 设备组
     * @return 结果
     */
    @Transactional
    @Override
    public int insertIotGroup(IotGroup iotGroup)   {
        passwordHandling(iotGroup);
        iotGroup.setUid(IdUtils.simpleUUID());
        Long userId = SecurityUtils.getUserId();
        boolean admin = SecurityUtils.isAdmin(userId);
        iotGroup.setCreateTime(DateUtils.getNowDate());
        iotGroup.setCreateBy(SecurityUtils.getUsername());
        //插入关联表数据

        int row = iotGroupMapper.insertIotGroup(iotGroup);

        IotGroupUser groupUser = new IotGroupUser();
        groupUser.setAdmin(true);
        groupUser.setGroupId(iotGroup.getGroupId());

        if (admin) {
            //如果是管理员可以选择该群组的创建者
            groupUser.setUserId(ObjectUtils.isEmpty(iotGroup.getAdminUserId()) ? userId : iotGroup.getAdminUserId());
        } else {
            //只能是本人创建
            groupUser.setUserId(userId);
        }

        iotGroupUserMapper.insertIotGroupUser(groupUser);
        AjaxResult ajaxResult = null;
        try {
            ajaxResult = mqttAuthService.addUser(iotGroup.getSecretKey(), AESUtil.decrypt(mysqlAES,iotGroup.getSecretValue()), iotGroup.getUid());
        } catch (Exception e) {
            throw new ServiceException("password解密失败");
        }
        if (!ajaxResult.isSuccess()) {
            throw new ServiceException("添加用户失败:" + ajaxResult.get(AjaxResult.MSG_TAG));
        }
        IotTopic iotTopic = new IotTopic();
        //alarms/告警配置id
//        iotTopic.setTopicName("alarms/+");
//        iotTopic.setGroupId(iotGroup.getGroupId());
//        iotTopic.setCreateBy(SecurityUtils.getUsername());
//        iotTopic.setCreateTime(DateUtils.getNowDate());
//        iotTopic.setUid(IdUtils.fastSimpleUUID());
//        iotTopic.setRemark("告警主题");
//        iotTopicMapper.insertIotTopic(iotTopic);
        return row;
    }

    /**
     * 修改设备组
     *
     * @param iotGroup 设备组
     * @return 结果
     */
    @Transactional
    @Override
    public int updateIotGroup(IotGroup iotGroup) {
        IotGroup old;
        if (SecurityUtils.isAdmin(SecurityUtils.getUserId())) {
            old = iotGroupMapper.selectIotGroupByGroupIdAndUserId(iotGroup.getGroupId(), null);
        } else {
            old = iotGroupMapper.selectIotGroupByGroupIdAndUserId(iotGroup.getGroupId(), iotGroup.getUserId());
        }
        if (ObjectUtils.isEmpty(old)) {
            throw new ServiceException("查找群组失败");
        }
        passwordHandling(iotGroup);
        //确保uid不会变换 不允许修改
        iotGroup.setUid(null);
        iotGroup.setUpdateTime(DateUtils.getNowDate());
        iotGroup.setUpdateBy(SecurityUtils.getUsername());
        boolean updatePrefix = StringUtils.hasText(iotGroup.getGroupPrefix()) && !old.getGroupPrefix().equals(iotGroup.getGroupPrefix());
        boolean updatePassword = StringUtils.hasText(iotGroup.getSecretValue()) && !old.getSecretValue().equals(iotGroup.getSecretValue());
        boolean updateUsername = StringUtils.hasText(iotGroup.getSecretKey()) && !old.getSecretKey().equals(iotGroup.getSecretKey());
        int i = iotGroupMapper.updateIotGroup(iotGroup);
        if (updatePrefix) {
            AjaxResult ajaxResult = mqttAuthService.editGroupPrefix(old.getGroupPrefix(), iotGroup.getGroupPrefix());
            if (!ajaxResult.isSuccess()) {
                throw new ServiceException("修改Prefix失败:" + ajaxResult.get(AjaxResult.MSG_TAG));

            }
        }
        JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("uid", old.getUid());
        if (updatePassword) {
            try {
                jsonObject.addProperty("password", AESUtil.decrypt(mysqlAES, iotGroup.getSecretValue()));
            } catch (Exception e) {
                throw new ServiceException("password解密失败");
            }

        }
        if (updateUsername) {
            jsonObject.addProperty("username", iotGroup.getSecretKey());
        }
        if (updatePassword || updateUsername) {
            AjaxResult ajaxResult = mqttAuthService.editUser(jsonObject);
            if (!ajaxResult.isSuccess()) {
                throw new ServiceException("修改用户或密码失败:" + ajaxResult.get(AjaxResult.MSG_TAG));

            }
        }

        return i;
    }

    private void passwordHandling(IotGroup iotGroup) {
        if (!StringUtils.hasText(iotGroup.getSecretValue())) {
            return;
        }
        try {
            String v = RsaUtils.decryptByPrivateKey(privateKeyRSA, iotGroup.getSecretValue());

            if (v != null) {
                iotGroup.setSecretValue(AESUtil.encrypt(mysqlAES, v));
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
            throw new ServiceException("mqtt密码加解密异常");
        }
    }

    /**
     * 批量删除设备组
     *
     * @param groupIds 需要删除的设备组主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteIotGroupByGroupIds(Long[] groupIds) {
        iotGroupUserMapper.deleteIotGroupUserByGroupIds(groupIds);
        return iotGroupMapper.deleteIotGroupByGroupIds(groupIds);
    }

    /**
     * 删除设备组信息
     *
     * @param groupId 设备组主键
     * @return 结果
     */
    @Override
    public int deleteIotGroupByGroupId(Long groupId) {
        return iotGroupMapper.deleteIotGroupByGroupId(groupId);
    }

    /**
     * 查询设备组当前成员
     */
    @Override
    public List<Map<String, Object>> selectAllocatedList(IotGroupUser user) {
        return iotGroupUserMapper.selectAllocatedList(user);

    }

    /**
     * 查询设备组当前可以添加的成员
     */
    @Override
    public List<Map<String, Object>> selectUnallocatedList(IotGroupUser user) {
        return iotGroupUserMapper.selectUnallocatedList(user);
    }

    /**
     * 添加成员
     *
     * @param groupId
     * @param userIds
     * @param permissions
     * @return
     */
    @Override
    public int insertGroupUsers(Long groupId, Long[] userIds, String[] permissions) {
        if (userIds.length != permissions.length) {
            throw new ServiceException("用户Id和权限Id不匹配");
        }
        Long userId = SecurityUtils.getUserId();
        boolean admin = SecurityUtils.isAdmin(userId);
        IotGroupUser userPermissions = hasUserPermissions(groupId, ADD_USER_PERMISSIONS);
        if (!admin && ObjectUtils.isEmpty(userPermissions)) {
            throw new ServiceException("无权限添加用户");
        }
        List<IotGroupUser> list = new ArrayList<IotGroupUser>();
        for (int i = 0; i < userIds.length; ++i) {
            IotGroupUser gr = new IotGroupUser();
            gr.setUserId(userIds[i]);
            gr.setPermissions(addPerm(permissions[i], userPermissions));
            gr.setGroupId(groupId);
            list.add(gr);
        }




        return iotGroupUserMapper.batchGroupUser(list);
    }

    private String addPerm(String permission, IotGroupUser iotGroupUser) {
        if (SecurityUtils.isAdmin(SecurityUtils.getUserId()) || iotGroupUser.getAdmin()) {
            return permission;
        }
        // 获取用户当前权限字符串
        String userPermissions = iotGroupUser.getPermissions();

        // 检查新权限是否超过用户当前权限
        for (int i = 0; i < permission.length(); i++) {
            char newPermChar = permission.charAt(i);
            char userPermChar = userPermissions.charAt(i);
            // 如果新权限的某一位是1，而用户当前权限的对应位是0，则抛出异常
            if (newPermChar == '1' && userPermChar == '0') {
                throw new ServiceException("不可以赋予比自己高的权限");
            }
        }

        return permission;
    }

    /**
     * 判断权限
     */
    private IotGroupUser hasUserPermissions(Long groupId, Integer index) {

        List<IotGroupUser> userGroup = iotGroupUserMapper.selectIotGroupUserListByUserId(SecurityUtils.getUserId());
        for (IotGroupUser item : userGroup) {
            if (groupId.equals(item.getGroupId()) && (item.getAdmin() || item.getPermissions().charAt(index - 1) == '1')) {
                return item;
            }
        }
        return null;
    }

    @Override
    public int deleteAuthUser(IotGroupUser iotGroupUser) {
        Long userId = SecurityUtils.getUserId();
        boolean admin = SecurityUtils.isAdmin(userId);
        IotGroupUser userPermissions = hasUserPermissions(iotGroupUser.getGroupId(), DELETE_USER_PERMISSIONS);
        if (!admin && ObjectUtils.isEmpty(userPermissions)) {
            throw new ServiceException("无权限删除用户");
        }
        return iotGroupUserMapper.deleteGroupUserInfo(iotGroupUser);
    }

    @Override
    public int deleteAuthUsers(Long groupId, Long[] userIds) {
        Long userId = SecurityUtils.getUserId();
        boolean admin = SecurityUtils.isAdmin(userId);
        IotGroupUser userPermissions = hasUserPermissions(groupId, DELETE_USER_PERMISSIONS);
        if (!admin && ObjectUtils.isEmpty(userPermissions)) {
            throw new ServiceException("无权限删除用户");
        }
        return iotGroupUserMapper.deleteGroupUserInfos(groupId, userIds);
    }

    @Override
    public IotGroupUser getMyPermissions(Long groupId) {
        IotGroupUser iotGroupUser = new IotGroupUser();
        iotGroupUser.setGroupId(groupId);
        iotGroupUser.setUserId(SecurityUtils.getUserId());
        List<IotGroupUser> iotGroupUsers = iotGroupUserMapper.selectIotGroupUserList(iotGroupUser);
        if (!iotGroupUsers.isEmpty()) {
            return iotGroupUsers.get(0);
        }
        return null;
    }


    public IotGroup getIotGroupByGroupId(Long groupId) {
        IotGroup iotGroup;
        if (SecurityUtils.isAdmin(SecurityUtils.getUserId())) {
            iotGroup = iotGroupMapper.selectIotGroupByGroupIdAndUserId(groupId, null);
        } else {
            iotGroup = iotGroupMapper.selectIotGroupByGroupIdAndUserId(groupId, SecurityUtils.getUserId());
        }
        if (ObjectUtils.isEmpty(iotGroup)) {
            throw new ServiceException("您无权修改此群组下的主题");
        }
        return iotGroup;
    }
}
